package com.panlin.daohang

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.Criteria
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.core.content.ContextCompat
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority

/**
 * Android定位工具类
 * 支持:
 * 1.系统GPS定位
 * 2.系统网络定位
 * 3.Google Fused定位
 */
class LocationUtils private constructor(private val context: Context) {

    // 系统定位管理器
    private var locationManager: LocationManager? = null
    // Google定位客户端
    private var fusedLocationClient: FusedLocationProviderClient? = null
    // 定位回调
    private var locationCallback: LocationResultCallback? = null
    // 超时Handler
    private var timeoutHandler: Handler? = null
    // 定位状态
    private var isLocating = false

    companion object {
        private const val TAG = "LocationUtils"
        // 定位超时时间
        private const val LOCATION_TIMEOUT = 15000L
        // 单例实例
        private var instance: LocationUtils? = null

        @Synchronized
        fun getInstance(context: Context): LocationUtils {
            if (instance == null) {
                instance = LocationUtils(context.applicationContext)
            }
            return instance!!
        }
    }

    init {
        // 初始化系统定位服务
        locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        // 初始化Google定位服务(如果可用)
        if (isGooglePlayServicesAvailable()) {
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        }
        // 初始化Handler
        timeoutHandler = Handler(Looper.getMainLooper())
    }

    /**
     * 定位结果回调接口
     */
    interface LocationResultCallback {
        fun onLocationSuccess(latitude: Double, longitude: Double)
        fun onLocationFailed(error: String)
    }

    /**
     * 开始定位
     */
    @SuppressLint("MissingPermission")
    fun startLocation(callback: LocationResultCallback) {
        // 避免重复定位
        if (isLocating) {
            return
        }

        this.locationCallback = callback
        isLocating = true

        // 检查权限
        if (!checkLocationPermission()) {
            isLocating = false
            callback.onLocationFailed("未获取定位权限")
            return
        }

        // 检查定位开关
        if (!isLocationEnabled()) {
            isLocating = false
            callback.onLocationFailed("定位未开启")
            return
        }

        // 设置超时
        timeoutHandler?.postDelayed({
            if (isLocating) {
                stopLocation()
                callback.onLocationFailed("定位超时")
            }
        }, LOCATION_TIMEOUT)

        // 尝试获取最后已知位置
        val lastLocation = getLastKnownLocation()
        if (lastLocation != null) {
            handleLocationResult(lastLocation)
            return
        }

        // 同时启动所有可用的定位方式

        // 1. 尝试GPS定位
        if (locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true) {
            startGPSLocation()
        }

        // 2. 尝试网络定位
        if (locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER) == true) {
            startNetworkLocation()
        }

        // 3. 尝试Google定位
        if (isGooglePlayServicesAvailable()) {
            startGoogleLocation()
        }

        // 如果所有定位方式都不可用
        if (locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) != true &&
            locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER) != true &&
            !isGooglePlayServicesAvailable()
        ) {
            isLocating = false
            callback.onLocationFailed("所有定位方式都不可用")
        }

        // 记录日志
        Log.d(TAG, "已启动定位 - GPS定位:${locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER)}, " +
                "网络定位:${locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER)}, " +
                "Google定位:${isGooglePlayServicesAvailable()}")
    }

    /**
     * GPS定位
     */
    @SuppressLint("MissingPermission")
    private fun startGPSLocation() {
        val criteria = Criteria()
        criteria.setAccuracy(Criteria.ACCURACY_FINE) // 设置定位精确度
        criteria.setAltitudeRequired(true) // 设置是否需要海拔信息
        criteria.setBearingRequired(true) // 设置是否需要方位信息
        criteria.setCostAllowed(true) // 设置是否允许运营商收费
        criteria.setPowerRequirement(Criteria.POWER_HIGH) // 设置对电源的需求
        val bestProvider = locationManager?.getBestProvider(criteria, true)
        Log.i(TAG, "GPS定位bestProvider: $bestProvider")
        if (locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true) {
            try {
                locationManager?.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    500L, // 最小时间间隔
                    0f,    // 最小距离变化
                    locationListener
                )
            } catch (e: Exception) {
                Log.e(TAG, "GPS定位异常: ${e.message}")
            }
        }
    }

    /**
     * 网络定位
     */
    @SuppressLint("MissingPermission")
    private fun startNetworkLocation() {
        if (locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER) == true) {
            try {
                locationManager?.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    1000L, // 最小时间间隔
                    0f,    // 最小距离变化
                    locationListener
                )
            } catch (e: Exception) {
                Log.e(TAG, "网络定位异常: ${e.message}")
            }
        }
    }

    /**
     * Google Fused定位
     */
    @SuppressLint("MissingPermission")
    private fun startGoogleLocation() {
        if (!isGooglePlayServicesAvailable()) {
            locationCallback?.onLocationFailed("系统定位和Google定位都不可用")
            return
        }

        try {
            // 创建定位请求
            val locationRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                // Android 12及以上使用新API
                LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000)
                    .setWaitForAccurateLocation(false)
                    .setMinUpdateIntervalMillis(3000)
                    .setMaxUpdateDelayMillis(10000)
                    .build()
            } else {
                // Android 12以下使用旧API
                LocationRequest().apply {
                    @Suppress("DEPRECATION")
                    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                    interval = 5000
                    fastestInterval = 3000
                }
            }

            // Google定位回调
            val googleLocationCallback = object : LocationCallback() {
                override fun onLocationResult(locationResult: LocationResult) {
                    locationResult.lastLocation?.let { location ->
                        handleLocationResult(location)
                    }
                }
            }

            // 请求位置更新
            fusedLocationClient?.requestLocationUpdates(
                locationRequest,
                googleLocationCallback,
                Looper.getMainLooper()
            )
        } catch (e: Exception) {
            Log.e(TAG, "Google定位异常: ${e.message}")
            e.printStackTrace()
            locationCallback?.onLocationFailed("Google定位失败: ${e.message}")
        }
    }

    /**
     * 系统定位监听器
     */
    private val locationListener = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            handleLocationResult(location)
        }

        override fun onProviderDisabled(provider: String) {
            Log.d(TAG, "定位提供者已禁用: $provider")
        }

        override fun onProviderEnabled(provider: String) {
            Log.d(TAG, "定位提供者已启用: $provider")
        }
    }

    /**
     * 获取最后已知位置
     */
    @SuppressLint("MissingPermission")
    private fun getLastKnownLocation(): Location? {
        try {
            // 优先使用GPS的最后位置
            var lastLocation = locationManager?.getLastKnownLocation(LocationManager.GPS_PROVIDER)

            // 如果GPS没有最后位置,尝试网络定位的最后位置
            if (lastLocation == null) {
                lastLocation = locationManager?.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
            }

            // 如果系统定位都没有,尝试Google定位的最后位置
            if (lastLocation == null && isGooglePlayServicesAvailable()) {
                fusedLocationClient?.lastLocation?.addOnSuccessListener { location ->
                    location?.let {
                        lastLocation = it
                    }
                }
            }

            // 检查位置是否在合理时间范围内(30分钟)
            if (lastLocation != null) {
                val timeDelta = System.currentTimeMillis() - lastLocation!!.time
                if (timeDelta > 30 * 60 * 1000) {
                    lastLocation = null
                }
            }

            return lastLocation
        } catch (e: Exception) {
            Log.e(TAG, "获取最后位置异常: ${e.message}")
            e.printStackTrace()
        }
        return null
    }

    /**
     * 处理定位结果
     */
    private fun handleLocationResult(location: Location) {
        if (!isLocating) return

        timeoutHandler?.removeCallbacksAndMessages(null)
        stopLocation()
        locationCallback?.onLocationSuccess(location.latitude, location.longitude)
    }

    /**
     * 停止定位
     */
    fun stopLocation() {
        isLocating = false

        // 停止系统定位
        try {
            locationManager?.removeUpdates(locationListener)
        } catch (e: Exception) {
            Log.e(TAG, "停止系统定位异常: ${e.message}")
        }

        // 停止Google定位
        try {
            fusedLocationClient?.removeLocationUpdates(object : LocationCallback() {})
        } catch (e: Exception) {
            Log.e(TAG, "停止Google定位异常: ${e.message}")
        }

        // 移除超时
        timeoutHandler?.removeCallbacksAndMessages(null)
    }

    /**
     * 检查定位权限
     */
    private fun checkLocationPermission(): Boolean {
        return ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(
                    context,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 检查定位是否开启
     */
    private fun isLocationEnabled(): Boolean {
        val gpsEnabled = locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER)
        val networkEnabled = locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

        Log.d(TAG, "定位状态 - GPS: $gpsEnabled, 网络: $networkEnabled")

        return gpsEnabled == true || networkEnabled == true
    }

    /**
     * 检查Google Play Services是否可用
     */
    private fun isGooglePlayServicesAvailable(): Boolean {
        try {
            val googleApiAvailability = GoogleApiAvailability.getInstance()
            val resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context)
            return resultCode == ConnectionResult.SUCCESS
        } catch (e: Exception) {
            Log.e(TAG, "检查Google Play Services异常: ${e.message}")
            return false
        }
    }
}